//$Id: FileSystemUtil.java,v 1.4 2008/11/25 08:26:13 liu-hengyu Exp $
/******************************************************************************
 * Created on 2008/09/09
 * Copyright(C) by www.atjava.com
 *
 *   ����         ������           �� ��
 * 2008/09/09      jin-dong          ������
 *
 ******************************************************************************/
package com.atjava.webspider.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

/**
 * @author  DCJ jin-dong
 * @version 1.0
 */
public class FileSystemUtil {

	/**
	 * File separator
	 */
	private static final String separator = File.separator;
	
	/**
	 * Line changer
	 */
	public static final String LINE_SPLITER;
	
	private int bufSize = 8192;
	
	private static final String DELFAULT_CHARSET = "UTF-8";
	
	static{
		LINE_SPLITER = System.getProperty("os.name").startsWith("Windows")?"\r\n":"\n";
	}
	
	public FileSystemUtil(){
		
	}
	
	public FileSystemUtil(int bufSize){
		this.bufSize = bufSize;
	}
	
	/**
	 * Receive file data from a InputStrean and save to the server
	 * @param is
	 * @param os
	 * @throws Exception
	 */
	public void readWriteData(InputStream is,OutputStream os) throws Exception{
		//open buffered input stream
		BufferedInputStream bis = new BufferedInputStream(is);
		//open buffered output stream
		BufferedOutputStream bos = new BufferedOutputStream(os);
		//
		byte [] buffer = new byte[bufSize];
		int n =0;
		try{
			//read stream
			while((n=bis.read(buffer)) != -1){
				//write
				bos.write(buffer,0,n);
			}
			bos.flush();
		}catch(Exception e){
			throw new Exception(e);
		}finally{
			//close stream
			close(bis);
			close(bos);
		}
	}
	
	public void writeText(String html,File aimFile) throws Exception{
		writeText(html, aimFile, DELFAULT_CHARSET);
	}
	
	public void writeText(String html,File aimFile,String charset) throws Exception{
		OutputStream os = new FileOutputStream(aimFile);
		try{
			writeText(html, os, charset);
		}catch(Exception e){
			throw new Exception(e);
		}finally{
			//close stream
			close(os);
		}
	}
	
	public void writeText(String html,OutputStream os) throws Exception{
		writeText(html, os, DELFAULT_CHARSET);
	}
	
	public void writeText(String html,OutputStream os,String charest) throws Exception{
		OutputStreamWriter osWriter = null;
		BufferedWriter bufWriter = null;
		try{
			osWriter = new OutputStreamWriter(os,charest);
			bufWriter = new BufferedWriter(osWriter);
			bufWriter.write(html);
		}catch(Exception e){
			throw new Exception(e);
		}finally{
			//close stream
			close(bufWriter);
			close(osWriter);
		}
	}
	
	/**
	 * Write the file to the assigned OutputStream.
	 * @param path
	 * @throws Exception
	 */
	public String readText(InputStream is) throws IOException{
		return readText(is,DELFAULT_CHARSET);
	}
	
	/**
	 * Write the file to the assigned OutputStream.
	 * @param path
	 * @throws Exception
	 */
	public String readText(InputStream is,String charset) throws IOException{
		InputStreamReader isReader = null;
		BufferedReader bufReader = null;
		try{
			isReader = new InputStreamReader(is,charset);
			bufReader = new BufferedReader(isReader);
			StringBuffer buffer = new StringBuffer();
			String line = null;
			while((line = bufReader.readLine()) != null){
				buffer.append(line);
				buffer.append(LINE_SPLITER);
			}
			return buffer.toString();
		}catch(IOException e){
			throw e;
		}finally{
			close(bufReader);
			close(isReader);
		}
	}
	
	public String readText(String filePath) throws IOException{
		InputStream is = null;
		try{
			is = new FileInputStream(filePath);
			return readText(is);
		}catch(IOException e){
			throw e;
		}finally{
			close(is);
		}
	}
	
	public String readText(String filePath,String charset) throws IOException{
		InputStream is = null;
		try{
			is = new FileInputStream(filePath);
			return readText(is,charset);
		}catch(IOException e){
			throw e;
		}finally{
			close(is);
		}
	}
	
	/**
	 * Write the file to the assigned OutputStream.
	 * @param path
	 * @throws Exception
	 */
	public void writeData(File file,OutputStream os) throws Exception{
		//open stream
		InputStream is = new FileInputStream(file);
		try {
			//read and write stream
			readWriteData(is, os);
		} catch (Exception e) {
			throw e;
		} finally{
			//close stream
			close(is);
		}
	}
	
	/**
	 * Write the file to the assigned OutputStream.
	 * @param path
	 * @throws Exception
	 */
	public void writeData(InputStream is,File file) throws Exception{
		//open stream
		OutputStream os = new FileOutputStream(file);
		try {
			//read and write stream
			readWriteData(is, os);
		} catch (Exception e) {
			throw e;
		} finally{
			//close stream
			close(os);
		}
	}
	
	/**
	 * Write the file to the assigned path.
	 * @param path
	 * @throws Exception
	 */
	public void writeData(File file,String filePath) throws Exception{
		//open stream
		InputStream is = new FileInputStream(file);
		OutputStream os = new FileOutputStream(filePath);
		//read and write stream
		readWriteData(is, os);
		//close stream
		close(is);
		close(os);
	}
	
	public static long getFileSize(File f)throws IOException{
		if(!f.exists())
			return 0;
		long size = 0;
		if(f.isDirectory()){
			File [] fList = f.listFiles();
			for(int i=0;i<fList.length;i++){
				size += getFileSize(fList[i]);
			}
			return size;
		}else {
			return f.length();
		}
	}
	
	public static List<File> getFilesList(File f,String exp){
		List<File> fileList = new ArrayList<File>();
		if(!f.exists())
			return fileList;
		if(f.isDirectory()){
			File [] fList = f.listFiles();
			for(int i=0;i<fList.length;i++){
				fileList.addAll(getFilesList(fList[i],exp));
			}
		}else {
			if(f.getName().toLowerCase().endsWith(exp)
			|| "*".equals(exp)){
				fileList.add(f);
			}
		}
		return fileList;
	}
	
	/**
	 * Copy to the assigned path.
	 * @param src
	 * @param aimPath
	 * @throws Exception
	 */
	public int copy(String srcPath , String aimPath) throws Exception{
		return copy(new File(srcPath), aimPath);
	}
	
	/**
	 * Copy a file or a directory to the assigned path.
	 * @param src
	 * @param aimPath
	 * @throws Exception
	 */
	public int copy(File src , String aimPath) throws Exception{
		int count = 0;
		File aim = new File(aimPath);
		if(!aim.exists())
			aim.mkdir();
		if(!aim.isDirectory())
			throw new Exception
			("Path : \"".concat(aimPath).concat("\" must be a available path."));
		String path = aimPath.concat(separator).concat(src.getName());
		//directory
		if(src.isDirectory()){
			File [] fList = src.listFiles();
			for(int i=0;i<fList.length;i++){
				//call copy method 
				count += copy(fList[i], path);
			}
		//file
		}else {
			//open stream
			InputStream is = new FileInputStream(src);
			OutputStream os = new FileOutputStream(path);
			//read and write stream
			readWriteData(is, os);
			count ++;
			//close stream
			close(is);
			close(os);
		}
		return count;
	}
	
	/**
	 * Delete assgned file
	 * @param f
	 */
	public void delete(File f){
		if(!f.exists())
			return ;
		if(f.isDirectory()){
			File [] fList = f.listFiles();
			for(int i=0;i<fList.length;i++){
				delete(fList[i]);
			}
		}//else {
		f.delete();
		//}
	}
	
	public void delete(String path){
		delete(new File(path));
	}
	
	/**
	 * Close a Object which implements the interface Closeable
	 * @param obj
	 * @throws IOException
	 */
	public static void close(Closeable obj){
		try{
			if(obj != null)
				obj.close();
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	
	public static String getFileType(String fileName){
		return fileName.substring
		(fileName.lastIndexOf(".")+1, fileName.length());
	}
	
	public static boolean isLogicFileType(String type){
		StringTokenizer stoken = new StringTokenizer(type,"/\\:*?\"<>|");
		return !(stoken.countTokens()>1 || type.length() > 6);
	}
	
	public static String getFileName(String path){
		
		int index1 = path.lastIndexOf(separator)+1;
		int index2 = path.lastIndexOf("/")+1;
		int index = index1 > index2 ? index1 : index2;
		return path.substring(index, path.length());
	}
}
